<template>
  <div class="permission-management-container">
    <!-- 顶部标题和按钮 -->
    <div class="header-section">
      <h2 class="page-title">权限管理</h2>
      <div class="header-actions">
        <a-button type="primary" @click="showAddModal">
          <template #icon><PlusOutlined /></template>
          新增权限
        </a-button>
        <a-button @click="refreshData" style="margin-left: 10px">
          <template #icon><ReloadOutlined /></template>
          刷新
        </a-button>
      </div>
    </div>

    <!-- 权限表格 -->
    <div class="table-section">
      <a-table
        :columns="columns"
        :data-source="processedPermissionList"
        :pagination="false"
        :loading="loading"
        rowKey="id"
        bordered
        :expandable="expandableConfig"
        :customRow="customRow"
      >
        <template #bodyCell="{ column, record }">
          <!-- 类型列 -->
          <template v-if="column.key === 'type'">
            <a-tag :color="getTypeColor(record.type)">
              {{ getTypeName(record.type) }}
            </a-tag>
          </template>
          
          <!-- 路由路径列 -->
          <template v-else-if="column.key === 'url'">
            {{ record.url || '-' }}
          </template>
          
          <!-- 操作列 -->
          <template v-else-if="column.key === 'action'">
            <a-space>
              <a-tooltip title="编辑">
                <a-button type="link" size="small" @click="editPermission(record)">
                  <template #icon><EditOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-tooltip title="分配权限">
                <a-button 
                  type="link" 
                  size="small" 
                  @click="showAssignModal()"
                  v-if="record.type == 1"
                >
                  <template #icon><SafetyOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-popconfirm 
                title="确定删除该权限吗？" 
                @confirm="deletePermission(record.id)"
              >
                <a-tooltip title="删除">
                  <a-button type="link" danger size="small">
                    <template #icon><DeleteOutlined /></template>
                  </a-button>
                </a-tooltip>
              </a-popconfirm>
            </a-space>
          </template>
        </template>
      </a-table>
    </div>

    <!-- 添加/编辑权限模态框 -->
    <a-modal
      v-model:open="modalVisible"
      :title="isEditing ? '编辑权限' : '新增权限'"
      width="600px"
      @ok="handleSubmit"
      @cancel="resetForm"
      :confirm-loading="submitting"
      :destroyOnClose="true"
    >
      <a-form
        ref="formRef"
        :model="form"
        :rules="formRules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <a-form-item label="权限名称" name="name">
          <a-input v-model:value="form.name" placeholder="请输入权限名称" />
        </a-form-item>
        
        <a-form-item label="权限标识" name="code">
          <a-input v-model:value="form.code" placeholder="如：sys:user:add" />
        </a-form-item>
        
        <a-form-item label="权限类型" name="type">
          <a-select v-model:value="form.type" placeholder="请选择权限类型" @change="handleTypeChange">
            <a-select-option :value="0">目录</a-select-option>
            <a-select-option :value="1">菜单</a-select-option>
            <a-select-option :value="2">按钮</a-select-option>
            <a-select-option :value="3">接口</a-select-option>
          </a-select>
        </a-form-item>
        
        <a-form-item label="父级权限" name="parentId">
          <a-tree-select
            v-model:value="form.parentId"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="permissionTree"
            placeholder="请选择父级权限"
            :field-names="{ label: 'name', value: 'id', children: 'children' }"
            tree-default-expand-all
            allow-clear
          />
        </a-form-item>
        
        <a-form-item label="路由路径" name="url" v-if="form.type !== 2">
          <a-input v-model:value="form.url" placeholder="请输入路由路径，如：/system/user" />
        </a-form-item>
        
        <a-form-item label="图标" name="icon" v-if="form.type !== 2">
          <a-input v-model:value="form.icon" placeholder="请输入图标class，如：user-outlined" />
        </a-form-item>
        
        <a-form-item label="排序" name="sort">
          <a-input-number v-model:value="form.sort" :min="0" style="width: 100%" />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 分配权限模态框 -->
    <a-modal
      v-model:open="assignModalVisible"
      :title="`分配权限`"
      width="800px"
      @ok="handleAssignSubmit"
      @cancel="assignModalVisible = false"
      :confirm-loading="assignLoading"
    >
      <a-alert
        v-if="assignError"
        :message="assignError"
        type="error"
        show-icon
        style="margin-bottom: 16px"
      />
      <div class="role-selector" style="margin-bottom: 16px">
        <a-select
          v-model:value="currentRoleId"
          style="width: 100%"
          placeholder="请选择角色"
          @change="handleRoleChange"
        >
          <a-select-option v-for="role in roleList" :key="role.id" :value="role.id">
            {{ role.name }} ({{ role.code }})
          </a-select-option>
        </a-select>
      </div>
      <a-tree
        v-model:checkedKeys="checkedPermissions"
        checkable
        :tree-data="fullPermissionTree"
        :field-names="{ title: 'name', key: 'id' }"
        :height="400"
      />
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, h } from 'vue'
import { useRouter } from 'vue-router'
import { 
  PlusOutlined, 
  EditOutlined, 
  DeleteOutlined, 
  SafetyOutlined,
  ReloadOutlined
} from '@ant-design/icons-vue'
import { message, type FormInstance } from 'ant-design-vue'

// 类型定义
interface Permission {
  id: number
  parentId: number | null
  name: string
  code: string
  type: number
  url?: string
  icon?: string
  sort: number
  children?: Permission[]
}

interface SysRole {
  id: number
  name: string
  code: string
}

interface RoleAssignPermissionDTO {
  roleId: number
  permissionIds: number[]
}

interface ApiResponse<T = any> {
  code: number
  message?: string
  data: T
}

interface TableColumn {
  title: string
  dataIndex?: string
  key: string
  width?: number
  fixed?: string
  customRender?: Function
}

// 路由和基础配置
const router = useRouter()
const baseUrl = import.meta.env.VITE_API_URL

// 响应式数据
const loading = ref(false)
const submitting = ref(false)
const assignLoading = ref(false)
const modalVisible = ref(false)
const assignModalVisible = ref(false)
const isEditing = ref(false)
const assignError = ref<string | null>(null)
const formRef = ref<FormInstance>()
const permissionList = ref<Permission[]>([])
const permissionTree = ref<Permission[]>([])
const fullPermissionTree = ref<Permission[]>([])
const checkedPermissions = ref<number[]>([])
const roleList = ref<SysRole[]>([])
const currentRoleId = ref<number | null>(null)

// 表单数据
const form = reactive({
  id: null as number | null,
  parentId: null as number | null,
  name: '',
  code: '',
  type: 0,
  url: '',
  icon: '',
  sort: 0
})

// 表单验证规则
const formRules = {
  name: [
    { required: true, message: '请输入权限名称', trigger: 'blur' },
    { max: 20, message: '长度不能超过20个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入权限标识', trigger: 'blur' },
    { 
      pattern: /^[a-z:._]+$/,
      message: '只能包含小写字母、冒号、点和下划线',
      trigger: 'blur'
    }
  ],
  type: [
    { required: true, message: '请选择权限类型', trigger: 'change' }
  ],
  url: [
    { 
      pattern: /^\/[a-zA-Z0-9/-]*$/,
      message: '必须以/开头，只能包含字母、数字、/和-',
      trigger: 'blur'
    }
  ],
  icon: [
    { 
      pattern: /^[a-z-]+$/,
      message: '只能包含小写字母和连字符',
      trigger: 'blur'
    }
  ],
  sort: [
    { required: true, message: '请输入排序值', trigger: 'blur' }
  ]
}

// 自定义行属性
const customRow = (record: Permission) => {
  return {
    'data-record-type': record.type,
  }
}

// 处理权限数据，构建树形结构
const processedPermissionList = computed(() => {
  const map = new Map<number, Permission>()
  const tree: Permission[] = []
  
  permissionList.value.forEach(item => {
    const children = (item.type === 2 || item.type === 3) ? undefined : []
    map.set(item.id, { ...item, children })
  })

  permissionList.value.forEach(item => {
    const node = map.get(item.id)
    if (item.parentId === 0 || item.parentId === null) {
      tree.push(node!)
    } else {
      const parent = map.get(item.parentId)
      if (parent && parent.children !== undefined) {
        parent.children!.push(node!)
      }
    }
  })

  tree.sort((a, b) => a.sort - b.sort)
  tree.forEach(item => {
    if (item.children) {
      item.children.sort((a, b) => a.sort - b.sort)
    }
  })

  return tree
})

// 展开配置
const expandableConfig = reactive({
  childrenColumnName: 'children',
  defaultExpandAllRows: true,
  expandIcon: ({ expanded, record }: { expanded: boolean; record: Permission }) => {
    const shouldShow = (record.type === 0 || record.type === 1) && 
                     record.children && 
                     record.children.length > 0
    return shouldShow ? 
      h('span', { class: 'expand-icon' }, expanded ? '-' : '+') : 
      null
  },
  rowExpandable: (record: Permission) => {
    return (record.type === 0 || record.type === 1) && 
           record.children && 
           record.children.length > 0
  }
})

// 表格列配置
const columns: TableColumn[] = [
  {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    width: 80,
    customRender: ({ record }: { record: Permission }) => {
      const indent = record.parentId && record.parentId !== 0 ? 24 : 0
      return h('span', { style: { paddingLeft: `${indent}px` } }, record.id)
    }
  },
  {
    title: '权限名称',
    dataIndex: 'name',
    key: 'name',
    width: 150,
    customRender: ({ record }: { record: Permission }) => {
      const indent = record.parentId && record.parentId !== 0 ? 24 : 0
      return h('span', { style: { paddingLeft: `${indent}px` } }, record.name)
    }
  },
  {
    title: '权限标识',
    dataIndex: 'code',
    key: 'code',
    width: 180
  },
  {
    title: '类型',
    key: 'type',
    width: 100
  },
  {
    title: '路由路径',
    key: 'url',
    width: 150
  },
  {
    title: '排序',
    dataIndex: 'sort',
    key: 'sort',
    width: 80
  },
  {
    title: '操作',
    key: 'action',
    width: 180,
    fixed: 'right'
  }
]

// 统一请求函数
const request = async <T = any>(
  url: string,
  options: RequestInit = {}
): Promise<ApiResponse<T>> => {
  const headers = {
    'Content-Type': 'application/json',
    'satoken': localStorage.getItem('token') || '',
    ...options.headers
  }

  try {
    const res = await fetch(`${baseUrl}${url}`, { ...options, headers })
    
    if (res.status === 401) {
      message.error('登录已过期，请重新登录')
      router.push('/login')
      throw new Error('Unauthorized')
    }

    if (!res.ok) {
      throw new Error(`HTTP error! status: ${res.status}`)
    }

    return await res.json()
  } catch (error) {
    console.error('API请求错误:', error)
    throw error
  }
}

// 构建树形结构
const buildTree = (permissions: Permission[]): Permission[] => {
  const map = new Map<number, Permission>()
  const tree: Permission[] = []
  
  permissions.forEach(item => {
    if (item.id && item.id !== item.parentId) {
      map.set(item.id, { ...item, children: [] })
    }
  })
  
  permissions.forEach(item => {
    if (!item.id) return
    
    const parent = item.parentId ? map.get(item.parentId) : null
    const current = map.get(item.id)
    
    if (parent && current) {
      parent.children?.push(current)
    } else if (current) {
      tree.push(current)
    }
  })
  
  return tree
}

// 获取所有角色
const fetchAllRoles = async () => {
  try {
    const res = await request<SysRole[]>('role/allRoles')
    if (res.code === 0) {
      roleList.value = res.data || []
    } else {
      message.error(res.message || '获取角色列表失败')
    }
  } catch (error) {
    console.error('获取角色列表错误:', error)
    message.error('获取角色列表失败')
  }
}

// 获取权限列表
const fetchPermissions = async () => {
  loading.value = true
  try {
    const res = await request<Permission[]>('permission/allMenu')
    if (res.code === 0) {
      permissionList.value = res.data || []
    } else {
      message.error(res.message || '获取权限列表失败')
    }
  } catch (error) {
    message.error('获取权限列表失败')
    console.error('获取权限列表错误:', error)
  } finally {
    loading.value = false
  }
}

// 获取权限树
const fetchPermissionTree = async () => {
  try {
    const res = await request<Permission[]>('permission/allMenu')
    if (res.code === 0) {
      permissionTree.value = buildTree(res.data || [])
    }
  } catch (error) {
    console.error('获取权限树错误:', error)
  }
}

// 获取角色已有权限
const fetchRolePermissions = async (roleId: number) => {
  try {
    const res = await request<number[]>(`role/getPermissions/${roleId}`)
    if (res.code === 0) {
      checkedPermissions.value = res.data || []
    } else {
      message.error(res.message || '获取角色权限失败')
    }
  } catch (error) {
    console.error('获取角色权限错误:', error)
    message.error('获取角色权限失败')
  }
}

// 显示添加模态框
const showAddModal = () => {
  isEditing.value = false
  resetForm()
  modalVisible.value = true
}

// 编辑权限
const editPermission = async (record: Permission) => {
  isEditing.value = true
  try {
    const res = await request<Permission>(`permission/getMenuById/${record.id}`)
    if (res.code === 0) {
      Object.assign(form, res.data)
      modalVisible.value = true
    } else {
      message.error(res.message || '获取权限详情失败')
    }
  } catch (error) {
    message.error('获取权限详情失败')
    console.error('编辑权限错误:', error)
  }
}

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value?.validate()
    submitting.value = true
    
    const url = isEditing.value 
      ? 'permission/updateMenu' 
      : 'permission/addMenu'
    const method = isEditing.value ? 'PUT' : 'POST'

    const res = await request(url, {
      method,
      body: JSON.stringify(form)
    })
    
    if (res.code === 0) {
      message.success(isEditing.value ? '权限更新成功' : '权限添加成功')
      modalVisible.value = false
      await Promise.all([fetchPermissions(), fetchPermissionTree()])
    } else {
      message.error(res.message || '操作失败')
    }
  } catch (error) {
    console.error('提交表单错误:', error)
    message.error('操作失败，请重试')
  } finally {
    submitting.value = false
  }
}

// 显示分配权限模态框
const showAssignModal = async () => {
  assignError.value = null
  assignLoading.value = true
  currentRoleId.value = null
  checkedPermissions.value = []
  
  try {
    // 获取所有角色
    await fetchAllRoles()
    
    // 获取完整权限树
    const treeRes = await request<Permission[]>('permission/allMenu')
    if (treeRes.code === 0) {
      fullPermissionTree.value = buildTree(treeRes.data || [])
      assignModalVisible.value = true
    } else {
      assignError.value = treeRes.message || '获取权限数据失败'
    }
  } catch (error) {
    assignError.value = '初始化分配权限失败'
    console.error('获取权限数据错误:', error)
  } finally {
    assignLoading.value = false
  }
}

// 角色选择变化
const handleRoleChange = (roleId: number) => {
  if (roleId) {
    fetchRolePermissions(roleId)
  } else {
    checkedPermissions.value = []
  }
}

// 提交权限分配
const handleAssignSubmit = async () => {
  if (!currentRoleId.value) {
    message.error('请选择角色')
    return
  }
  
  if (!checkedPermissions.value || checkedPermissions.value.length === 0) {
    message.error('请至少选择一个权限')
    return
  }

  assignLoading.value = true
  try {
    const requestData: RoleAssignPermissionDTO = {
      roleId: currentRoleId.value,
      permissionIds: checkedPermissions.value
    }

    const res = await request('role/addRoleToPermissions', {
      method: 'POST',
      body: JSON.stringify(requestData)
    })
    
    if (res.code === 0) {
      message.success('权限分配成功')
      assignModalVisible.value = false
    } else {
      message.error(res.message || '权限分配失败')
    }
  } catch (error) {
    console.error('分配权限错误:', error)
    message.error('权限分配失败，请重试')
  } finally {
    assignLoading.value = false
  }
}

// 删除权限
const deletePermission = async (id: number) => {
  loading.value = true
  try {
    const res = await request(`permission/deleteMenu/${id}`, {
      method: 'DELETE'
    })
    
    if (res.code === 0) {
      message.success('删除成功')
      await Promise.all([fetchPermissions(), fetchPermissionTree()])
    } else {
      message.error(res.message || '删除失败')
    }
  } catch (error) {
    console.error('删除权限错误:', error)
    message.error('删除失败，请重试')
  } finally {
    loading.value = false
  }
}

// 重置表单
const resetForm = () => {
  formRef.value?.resetFields()
  Object.assign(form, {
    id: null,
    parentId: null,
    name: '',
    code: '',
    type: 0,
    url: '',
    icon: '',
    sort: 0
  })
}

// 处理权限类型变化
const handleTypeChange = (value: number) => {
  if (value === 2) {
    form.url = ''
    form.icon = ''
  }
}

// 获取权限类型名称
const getTypeName = (type: number) => {
  const types = ['目录', '菜单', '按钮', '接口']
  return types[type] || '未知'
}

// 获取权限类型颜色
const getTypeColor = (type: number) => {
  const colors = ['blue', 'green', 'orange', 'red']
  return colors[type] || 'default'
}

// 刷新数据
const refreshData = () => {
  fetchPermissions()
  fetchPermissionTree()
  message.success('数据已刷新')
}

// 初始化
onMounted(() => {
  fetchPermissions()
  fetchPermissionTree()
  fetchAllRoles()
})
</script>

<style scoped>
.permission-management-container {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

.header-actions {
  display: flex;
  align-items: center;
}

.table-section {
  margin-top: 20px;
}

/* 操作按钮间距 */
:deep(.ant-space) {
  gap: 8px !important;
}

/* 表格样式优化 */
:deep(.ant-table) {
  border-radius: 8px;
  overflow: hidden;
}

:deep(.ant-table-thead > tr > th) {
  background: #fafafa;
  font-weight: 600;
}

/* 表格滚动条样式 */
:deep(.ant-table-body) {
  scrollbar-width: thin;
  scrollbar-color: #d9d9d9 #f5f5f5;
}

:deep(.ant-table-body::-webkit-scrollbar) {
  height: 8px;
  width: 8px;
}

:deep(.ant-table-body::-webkit-scrollbar-thumb) {
  background-color: #d9d9d9;
  border-radius: 4px;
}

:deep(.ant-table-body::-webkit-scrollbar-track) {
  background-color: #f5f5f5;
}

/* 完全隐藏所有不需要的展开图标单元格 */
:deep(.ant-table-row) .ant-table-row-expand-icon-cell {
  display: none !important;
}

/* 只显示目录和菜单类型的展开图标 */
:deep(.ant-table-row[data-record-type="0"]) .ant-table-row-expand-icon-cell,
:deep(.ant-table-row[data-record-type="1"]) .ant-table-row-expand-icon-cell {
  display: table-cell !important;
}

/* 隐藏按钮和接口类型的行前面的空白 */
:deep(.ant-table-row[data-record-type="2"]),
:deep(.ant-table-row[data-record-type="3"]) {
  & > td:first-child {
    padding-left: 16px !important;
  }
}

/* 模态框内容区域滚动 */
:deep(.ant-modal-body) {
  max-height: 60vh;
  overflow-y: auto;
}

/* 展开图标样式 */
.expand-icon {
  display: inline-block;
  width: 16px;
  height: 16px;
  line-height: 16px;
  text-align: center;
  margin-right: 8px;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  cursor: pointer;
  background: #fff;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .header-section {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .header-actions {
    width: 100%;
    justify-content: space-between;
  }
  
  :deep(.ant-table) {
    width: 100%;
    overflow-x: auto;
  }
}

/* 分配权限模态框样式 */
.role-selector {
  margin-bottom: 16px;
}

:deep(.ant-tree) {
  background: #fff;
}
</style>